package com.demo.config;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;

/**
 * 自定义 ThreadPoolTaskExecutor，每次执行方法时，输出线程池信息
 * @author ytzhu
 *
 */
public class VisiableThreadPoolTaskExecutor extends ThreadPoolTaskExecutor{
	
	private Log log = LogFactory.getLog(this.getClass()) ;

	public void showThreadPoolInfo(String prefix) {
		ThreadPoolExecutor threadPoolExecutor = this.getThreadPoolExecutor() ;
		if(null == threadPoolExecutor) {
			return ;
		}
		this.log.info( this.getThreadNamePrefix()+","
                + prefix+","
                + "taskCount ["+ threadPoolExecutor.getTaskCount() +"],"
                + "completedTaskCount ["+threadPoolExecutor.getCompletedTaskCount()+"],"
                + "activeCount ["+ threadPoolExecutor.getActiveCount() +"],"
                + "queueSize ["+threadPoolExecutor.getQueue().size() +"]"
				);
	}
	
	@Override
	public void execute(Runnable task) {
		this.showThreadPoolInfo("execute(Runnable)");
		super.execute(task);
	}

	@Override
	public void execute(Runnable task, long startTimeout) {
		this.showThreadPoolInfo("execute(Runnable,long)");
		super.execute(task, startTimeout);
	}

	@Override
	public Future<?> submit(Runnable task) {
		this.showThreadPoolInfo("submit(Runnable)");
		return super.submit(task);
	}

	@Override
	public <T> Future<T> submit(Callable<T> task) {
		this.showThreadPoolInfo("submit(Callable)");
		return super.submit(task);
	}

	@Override
	public ListenableFuture<?> submitListenable(Runnable task) {
		this.showThreadPoolInfo("submitListenable(Runnable)");
		return super.submitListenable(task);
	}

	@Override
	public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
		this.showThreadPoolInfo("submitListenable(Callable)");
		return super.submitListenable(task);
	}
	
}
